package com.legsem.jhosync.jmeter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Load test a sync server.
 * <p/>
 * These tests are meant to run within JMeter's JUnit sampler.
 * 
 */
public class LoadTest extends AbstractTest {

    private Log log = LogFactory.getLog(LoadTest.class);

    /**
     * JMeter calls this constructor passing any text parameter entered in the
     * JMeter configuration.
     * 
     * @param initParms initial parameters
     */
    public LoadTest(String initParms) {
        super(initParms);
    }

    /**
     * Query the server for fresh data (this assumes the user is logged in and
     * client ID was already created). If a Token is received, we issue an
     * additional Query to acknowledge the token.
     * <p/>
     * The server may send data in chunks (pages), therefore we loop until there
     * are no more pages to acknowledge.
     * <p/>
     * This may lead to an infinite loop if the backend data is volatile and the
     * sync server keeps finding changes while the client is still receiving
     * pages from an earlier set of changes.
     * <p/>
     * This load test client will throw an exception in that last situation.
     * 
     * @throws Exception if anything goes wrong
     */
    public void testQuery() throws Exception {
        try {
            UserContext context = getUserContext();
            if (log.isDebugEnabled()) {
                log.debug("testQuery for " + context.toString());
            }

            String querySource = get("?client_id=" + context.client_id
                    + "&p_size=" + getPageSize() + "&version=3&source_name="
                    + getSourceName());
            context.token = match(TOKEN_PATTERN, querySource);
            int total_count = Integer.parseInt(match(TOTAL_COUNT_PATTERN,
                    querySource));
            int progress_count = Integer.parseInt(match(PROGRESS_COUNT_PATTERN,
                    querySource));
            while (context.token.length() > 0) {
                querySource = get("?client_id=" + context.client_id
                        + "&p_size=" + getPageSize()
                        + "&version=3&source_name=" + getSourceName()
                        + "&token=" + context.token);
                context.token = match(TOKEN_PATTERN, querySource);
                total_count = Integer.parseInt(match(TOTAL_COUNT_PATTERN,
                        querySource));

                int new_progress_count = Integer.parseInt(match(
                        PROGRESS_COUNT_PATTERN, querySource));
                if (new_progress_count > progress_count) {
                    progress_count = new_progress_count;
                } else {
                    throw new RuntimeException("Server overloaded");
                }
            }
            assertEquals(total_count, progress_count);
        } catch (Exception e) {
            log.error("testQuery failed", e);
            throw e;
        }

    }

}
